package cn.com.pajx.pajx_visitor_v3.base;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewStub;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;

import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.webp.decoder.WebpDrawable;
import com.bumptech.glide.integration.webp.decoder.WebpDrawableTransformation;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.CenterInside;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.google.gson.Gson;
import com.pajx.facelibrary.utils.DensityUtil;

import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Locale;

import butterknife.ButterKnife;
import cn.com.pajx.pajx_visitor_v3.R;
import cn.com.pajx.pajx_visitor_v3.bean.SchoolBean;
import cn.com.pajx.pajx_visitor_v3.bean.VisiteBean;
import cn.com.pajx.pajx_visitor_v3.broadcast.NetBroadcastReceiver;
import cn.com.pajx.pajx_visitor_v3.mvp.view.IBaseView;
import cn.com.pajx.pajx_visitor_v3.ui.activity.CommonSuccessActivity;
import cn.com.pajx.pajx_visitor_v3.ui.view.TimerCount;
import cn.com.pajx.pajx_visitor_v3.ui.view.dialog.LoadingDialog;
import cn.com.pajx.pajx_visitor_v3.ui.view.statelayout.StateLayoutHelper;
import cn.com.pajx.pajx_visitor_v3.utils.ActivityManagerUtil;
import cn.com.pajx.pajx_visitor_v3.utils.AppConstant;
import cn.com.pajx.pajx_visitor_v3.utils.Base64Utils;
import cn.com.pajx.pajx_visitor_v3.utils.LogUtils;
import cn.com.pajx.pajx_visitor_v3.utils.SharePreferencesUtil;
import cn.com.pajx.pajx_visitor_v3.utils.ToastUtil;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;
import pub.devrel.easypermissions.PermissionRequest;

/**
 * create by ruancw on 2024/2/28.
 * activity的基类
 */
public abstract class BaseActivity extends AppCompatActivity implements IBaseView, NetBroadcastReceiver.NetStatusMonitor, EasyPermissions.PermissionCallbacks {

    protected Context mContext;
    protected LinearLayout mToolbar;//顶部标题栏toolbar
    protected RelativeLayout viewHead;//顶部标题栏toolbar
    protected ImageView ivCommon;//返回与删除
    protected TextView tvHeadTitle, tvMiddleTitle, tvDownTimer;//中间标题
    protected ViewStub viewStubRight, viewStubLeft;//顶部标题栏右侧viewStub
    protected LoadingDialog mLoadingDialog;//进度对话框
    protected TimerCount countDownTimer;
    private boolean netStatus;//网络状态
    //监控网络的广播
    private NetBroadcastReceiver netBroadcastReceiver;
    private RelativeLayout viewNet;//网络状态的监听显示
    protected StateLayoutHelper helper;
    private TextToSpeech textToSpeech;//语音播报
    protected WebpDrawable webpDrawable;
    private long millsFuture = 60000;

    @Override
    protected void onStart() {
        super.onStart();
        //注册网络状态监听的广播
        registerBroadcastReceiver();
    }

    /**
     * 注册网络状态广播
     */
    private void registerBroadcastReceiver() {
        //注册广播
        if (netBroadcastReceiver == null) {
            netBroadcastReceiver = new NetBroadcastReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver(netBroadcastReceiver, filter);
            //设置监听
            netBroadcastReceiver.setStatusMonitor(this);
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        initFullScreen();
        beforeSetContentView();
        setContentView(getLayoutId());
        ButterKnife.bind(this);
        mLoadingDialog = new LoadingDialog(mContext);
        handleSavedInstanceState(savedInstanceState);
        initHead();
        initFullScreen(mToolbar);
        initView();
        ActivityManagerUtil.getInstant().addToPool(this);
    }

    public void initFullScreen() {
        dynamicHideNavigationBar();
        //不锁屏
        initKeyguardDisEnable();
    }

    /**
     * 沉浸式状态栏
     * 需要设置fitSystemWindows为false,theme中设置的全局为true
     *
     * @param view 需要沉浸的view
     */
    protected void initFullScreen(View view) {
        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
        int statusBarHeight = DensityUtil.getStatusBarHeight(mContext);
        if (!isFullScreen()) statusBarHeight = 0;
        view.setPadding(0, statusBarHeight, 0, 0);
    }

    /**
     * 初始化标题栏
     */
    private void initHead() {
        mToolbar = findViewById(R.id.toolbar);
        viewHead = findViewById(R.id.view_toolbar_head);
        viewNet = findViewById(R.id.view_net);
        if (hasHeadTitle()) {
            tvHeadTitle = findViewById(R.id.tv_head_title);
            tvMiddleTitle = findViewById(R.id.tv_middle_title);
            viewStubRight = findViewById(R.id.head_view_stub);
            viewStubLeft = findViewById(R.id.viwe_stub_left);
            tvDownTimer = findViewById(R.id.tv_down_timer);
            tvHeadTitle.setVisibility(isBackView() ? View.INVISIBLE : View.VISIBLE);
            tvHeadTitle.setText(loadHeadTitle());
            if (isBackView()) {
                setViewStubLayout(viewStubLeft, R.layout.view_stub_back).setOnClickListener(onBackClickListener);
            } else {
                setViewStubImageRes(viewStubLeft, R.mipmap.main_logo);
            }
        }
    }

    /**
     * 设置设备不锁屏
     */
    private void initKeyguardDisEnable() {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }

    /**
     * 隐藏底部导航栏
     */
    public void dynamicHideNavigationBar() {
        Window window = getWindow();
        // 保持布局状态,隐藏底部导航,隐藏导航栏
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /*| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN*/;
        uiOptions |= 0x00001000;
        window.getDecorView().setSystemUiVisibility(uiOptions);
        window.getDecorView().setOnSystemUiVisibilityChangeListener(visibility -> dynamicHideNavigationBar());
        //保持屏幕常亮
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    /**
     * 启动定时器
     */
    protected void initDownTimer() {
        cancelDownTimer();
        countDownTimer = new TimerCount(millsFuture, 1000, tvDownTimer);
        countDownTimer.setOnTimerFinish(this::onClickBack);
        countDownTimer.start();
    }

    protected void resetDownTimer() {
        if (isTimerStart()) {
            if (tvDownTimer != null) tvDownTimer.setVisibility(View.VISIBLE);
            initDownTimer();
        }
    }

    protected abstract void beforeSetContentView();

    protected abstract int getLayoutId();

    protected abstract void initView();

    protected void handleSavedInstanceState(Bundle savedInstanceState) {

    }

    protected void loadMillsFuture(long millsFuture) {
        this.millsFuture = millsFuture;
    }

    /**
     * 是否开启计时器
     *
     * @return 默认开启
     */
    protected boolean isTimerStart() {
        return true;
    }

    /**
     * 当前activity是否有fragment
     *
     * @return 默认没有为false
     */
    protected boolean isFullScreen() {
        return true;
    }

    /**
     * 当前activity是否有fragment
     *
     * @return 默认没有为false
     */
    protected boolean isExcute() {
        return true;
    }

    /**
     * 设置StateHelperView
     *
     * @param view 需要替换的View
     */
    protected void setHelperView(View view) {
        helper = new StateLayoutHelper(view);
    }

    /**
     * 设置标题栏标题
     *
     * @param title 标题
     */
    protected void setHeadTitle(String title) {
        if (hasHeadTitle()) {
            tvMiddleTitle.setText(title);
        }
    }

    /**
     * 设置标题栏图标
     *
     * @param drawableRes 图标
     * @return ImageView
     */
    protected ImageView setViewStubImageRes(ViewStub viewStub, @DrawableRes int drawableRes) {
        viewStub.setLayoutResource(R.layout.view_stub_img);
        ImageView mViewStubToolbarImage = (ImageView) viewStub.inflate();
        mViewStubToolbarImage.setImageResource(drawableRes);
        return mViewStubToolbarImage;
    }

    /**
     * 设置ViewStub 的布局
     *
     * @param layout_id
     * @return view
     */
    protected View setViewStubLayout(ViewStub viewStub, int layout_id) {
        viewStub.setLayoutResource(layout_id);
        return viewStub.inflate();
    }

    /**
     * 设置标题栏viewStub为text
     *
     * @param des 描述内容
     * @return TextView
     */
    protected TextView setViewStubText(String des) {
        if (hasHeadTitle()) {
            viewStubRight.setLayoutResource(R.layout.view_stub_text);
            TextView mViewStubToolbarText = (TextView) viewStubRight.inflate();
            mViewStubToolbarText.setText(des);
            return mViewStubToolbarText;
        }

        return null;
    }

    /**
     * 是否显示标题栏返回键
     *
     * @return 默认显示 true
     */
    protected boolean isBackView() {
        return true;
    }

    /**
     * 是否显示删除按钮
     *
     * @return 默认不显示 false
     */
    protected boolean isShowDeleteView() {
        return false;
    }

    /**
     * 是否显示标题栏
     *
     * @return 默认显示 true
     */
    protected boolean hasHeadTitle() {
        return true;
    }

    @Override
    public void showProgress() {
        if (mLoadingDialog != null) {
            mLoadingDialog.show();
        }
    }

    @Override
    public void showProgress(String message) {
        if (mLoadingDialog != null) {
            mLoadingDialog.setMessage(message).show();
        }
    }

    @Override
    public void hideProgress(String tag) {
        if (mLoadingDialog != null) {
            mLoadingDialog.dismiss();
        }
    }

    @Override
    public void onSuccess(String data, String aesKey, String message, int code, String tag) {

    }

    @Override
    public void onError(String message, int code, String tag) {
        ToastUtil.toast(message);
    }

    @Override
    public void onFailed(Throwable throwable, String tag) {

    }

    /**
     * 监听返回按钮事件
     */
    private final View.OnClickListener onBackClickListener = v -> onClickBack();

    @Override
    public void onBackPressed() {
        if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
            onClickBack();
        } else {
            getSupportFragmentManager().popBackStack();
        }
    }

    //监听返回键
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (getSupportFragmentManager().getBackStackEntryCount() <= 0) {
                onClickBack();
            } else {
                getSupportFragmentManager().popBackStack();
            }
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }


    protected void onClickBack() {
        finish();
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //清除屏幕常亮
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        ActivityManagerUtil.getInstant().popPool(this);
        if (mLoadingDialog != null) {
            mLoadingDialog.dismiss();
            mLoadingDialog = null;
        }
        if (netBroadcastReceiver != null) {
            //注销广播
            unregisterReceiver(netBroadcastReceiver);
        }

        cancelDownTimer();
    }

    protected void cancelDownTimer() {
        if (countDownTimer != null) countDownTimer.cancel();
    }

    @Override
    public void onNetChange(boolean netStatus) {
        this.netStatus = netStatus;
        isNetConnect();
    }

    /**
     * 监听网络状态做出相应改变
     */
    private void isNetConnect() {
        Message message = new Message();
        if (netStatus) {
            message.what = 99;
        } else {
            message.what = 100;
        }
        handler.sendMessage(message);

    }

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        @Override
        public void handleMessage(@NotNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 100) {
                viewNet.setVisibility(View.VISIBLE);
            } else {
                viewNet.setVisibility(View.GONE);
            }
        }
    };

    //参数检查
    protected boolean checkNullParam(String... params) {
        for (String param : params) {
            if (param == null) {//此app种有允许传递字符串为"" 的情况，所以用是否为空对象来判断
                ToastUtil.toast("关键参数不能为空");
                return true;
            }
        }
        return false;
    }

    /**
     * 关闭软键盘
     */
    protected void hideSoftInput() {
        // 虚拟键盘隐藏 判断view是否为空
        View decorView = getWindow().peekDecorView();
        if (decorView != null) {
            // 隐藏虚拟键盘
            InputMethodManager inputManger = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
            assert inputManger != null;
            inputManger.hideSoftInputFromWindow(decorView.getWindowToken(), 0);
        }
    }

    // 判断当前EditText是否可滚动
    protected boolean canVerticalScroll(EditText editText) {
        //滚动的距离
        int scrollY = editText.getScrollY();
        //控件内容的总高度
        int scrollRange = editText.getLayout().getHeight();
        //控件实际显示的高度
        int scrollExtent = editText.getHeight() - editText.getCompoundPaddingTop() - editText.getCompoundPaddingBottom();
        //控件内容总高度与实际显示高度的差值
        int scrollDifference = scrollRange - scrollExtent;
        if (scrollDifference == 0) {
            return false;
        }
        return (scrollY > 0) || (scrollY < scrollDifference - 1);
    }

    /**
     * 检查是否有tps550的Api
     *
     * @return boolean
     */
    protected boolean checkPackage() {
        PackageManager manager = this.getPackageManager();
        Intent intent = new Intent().setPackage("com.telpo.tps550.api");
        @SuppressLint({"WrongConstant", "QueryPermissionsNeeded"})
        List<ResolveInfo> resolveInfo = manager.queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS);
        return resolveInfo.size() >= 1;
    }

    /**
     * 开启设置安装未知来源应用权限界面
     *
     * @param context context
     */
    public void startInstallPermissionSetting(Context context) {
        ToastUtil.toast("请开启未知应用安装权限");
        if (context == null) {
            return;
        }
        Intent intent = new Intent();
        //设置不同版本跳转未知应用的动作
        if (Build.VERSION.SDK_INT >= 26) {
            intent.setAction(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        } else {
            intent.setAction(android.provider.Settings.ACTION_SECURITY_SETTINGS);
        }
        int INSTALL_UN_KNOW_APP_CODE = 0x101;
        startActivityForResult(intent, INSTALL_UN_KNOW_APP_CODE);
    }

    /**
     * 中文语音播报
     *
     * @param content 播报的文字
     */
    protected void speckChinese(String content) {
        textToSpeech = new TextToSpeech(this, status -> {
            LogUtils.e("status=" + status);
            if (status == TextToSpeech.SUCCESS) {
                int result = textToSpeech.setLanguage(Locale.CHINESE);
                if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    ToastUtil.toast("不支持中文播报");
                } else {
                    textToSpeech.speak(content, TextToSpeech.QUEUE_FLUSH, null);
                }
            } else {
                LogUtils.e("未检测到语音引擎");
//                ToastUtil.toast("未检测到语音引擎");
            }
        });
        //播报进度
        textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
            @Override
            public void onStart(String s) {

            }

            @Override
            public void onDone(String s) {
                if (textToSpeech != null) {
                    textToSpeech.stop(); // 不管是否正在朗读TTS都被打断
                    textToSpeech.shutdown(); // 关闭，释放资源
                }
            }

            @Override
            public void onError(String s) {

            }
        });
    }

    /**
     * webp的动画效果
     */
    protected void webpAnimate(ImageView ivAnimate, int animate) {
        Glide.with(mContext).load(animate)
                .optionalTransform(WebpDrawable.class, new WebpDrawableTransformation(new CenterInside()))
                .addListener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        webpDrawable = (WebpDrawable) resource;
                        webpDrawable.setLoopCount(999);
                        webpDrawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                            @Override
                            public void onAnimationStart(Drawable drawable) {
                                super.onAnimationStart(drawable);
                            }

                            @Override
                            public void onAnimationEnd(Drawable drawable) {
                                super.onAnimationEnd(drawable);
                            }
                        });

                        return false;
                    }
                }).into(ivAnimate);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (MotionEvent.ACTION_DOWN == event.getAction() || MotionEvent.ACTION_MOVE == event.getAction()) {
            resetDownTimer();
        }
        return super.onTouchEvent(event);
    }

    protected void skip2Success(String type) {
        Intent intent = new Intent(mContext, CommonSuccessActivity.class);
        intent.putExtra(AppConstant.TYPE, type);
        startActivity(intent);
        finish();
    }

    protected String loadSchoolName() {
        String schoolData = SharePreferencesUtil.getInstance().getString(AppConstant.SCHOOL_BEAN);
        SchoolBean schoolBean = new Gson().fromJson(schoolData, SchoolBean.class);
        if (schoolBean != null) {
            return schoolBean.getScl_name();
        }
        return "";
    }

    protected String loadVisiteId(String jsonData) {
        if (TextUtils.isEmpty(jsonData)) return "";
        try {
            String decodeData = Base64Utils.base64Decode(handleEscapeData(jsonData));
            VisiteBean visiteBean = new Gson().fromJson(decodeData, VisiteBean.class);
            if (visiteBean != null) {
                return visiteBean.getVis_id();
            }
        } catch (Exception e) {
            e.getStackTrace();
            speckChinese("二维码内容解析错误");
            ToastUtil.toast("二维码内容解析错误");
//            return "";
        }
        return "";
    }

    /**
     * 处理转义字符
     *
     * @param escapeData 转义字符串
     * @return 处理后的字符串
     */
    private String handleEscapeData(String escapeData) {
        if (escapeData.contains("\\000026")) {
            escapeData = escapeData.replace("\\000026", "");
            handleEscapeData(escapeData);
        }
        return escapeData;
    }

    @NonNull
    protected String loadHeadTitle() {
        return TextUtils.isEmpty(loadSchoolName()) ? "人脸识别访客系统" : loadSchoolName() + "访客系统";
    }

    /**
     * 动态检测敏感权限
     */
    protected void initCheckPermissions(String[] permissions, int permsRequestCode, String permsRequestDes) {
        //判断是否是6.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //手机状态权限动态申请
            applyPermissions(permissions, permsRequestCode, permsRequestDes);
        } else {
            //执行敏感行为操作
            onPermissionsExcute();
        }
    }

    /**
     * 判断是否有读取手机状态权限
     */
    public void applyPermissions(String[] permissions, int permsRequestCode, String permsRequestDes) {
        if (EasyPermissions.hasPermissions(mContext, permissions)) {
            // 已经申请过相机和存储权限
            onPermissionsExcute();
        } else {
            // 没有申请过相机和存储权限，现在去申请
            EasyPermissions.requestPermissions(
                    new PermissionRequest.Builder(BaseActivity.this, permsRequestCode, permissions)
                            .setRationale(permsRequestDes)
                            .setPositiveButtonText("允许")
                            .setNegativeButtonText("拒绝")
                            .build());
        }
    }

    /**
     * 权限申请成功执行操作
     */
    protected void onPermissionsExcute() {

    }

    /**
     * 敏感权限申请拒绝申请提示
     */
    protected String loadDeniedDes() {
        return "敏感权限";
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        //权限申请成功
        onPermissionsExcute();
    }

    @RequiresApi(api = Build.VERSION_CODES.R)
    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        LogUtils.e("perms=" + perms);
        //授权被拒绝，弹出提示框
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog
                    .Builder(this)
                    .setTitle("权限申请")
                    .setRationale("获取" + loadDeniedDes() + "，是否打开设置")
                    .setPositiveButton("设置")
                    .setNegativeButton("取消")
                    .build()
                    .show();
        }
    }
}
